package cn.jfstu.freenote.mvc.controller.base;

import cn.jfstu.freenote.exception.base.BaseException;
import cn.jfstu.freenote.exception.extend.AppException;
import cn.jfstu.freenote.exception.extend.SysException;
import cn.jfstu.freenote.exception.message.ExceptionCode;
import cn.jfstu.freenote.mvc.controller.response.ErrResponse;
import cn.jfstu.freenote.util.time.DateTimeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.springframework.web.servlet.support.RequestContext;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.beans.PropertyEditorSupport;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.util.Date;
import java.util.Locale;
import java.util.ResourceBundle;

/**
 * 控制器基类
 *
 * @author 贾俊峰
 * @version 1.0
 * @date 2016/12/26 16:32
 */
@Controller
public abstract class BaseController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 异常处理
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ErrResponse handleException(Exception ex, HttpSession session, HttpServletRequest request) throws UnsupportedEncodingException {
        logger.error(ex.getMessage());
        boolean isAppException = false;
        BaseException exception;
        if (ex instanceof SysException) {
            exception = (SysException) ex;
        } else if (ex instanceof AppException) {
            isAppException = true;
            exception = (AppException) ex;
        } else if (ex instanceof NullPointerException || ex instanceof ArrayIndexOutOfBoundsException
                || ex instanceof IOException) {
            exception = new SysException(ExceptionCode.SYSTEM_ERROR);// 系统错误
        } else {
            exception = new SysException(ExceptionCode.UNKNOWN_ERROR);// 未知错误
        }
        if (!isAppException) {//不打印应用异常
            ex.printStackTrace();
        }

        // 输出国际化的异常信息
        String msg = null;
        Locale locale = (Locale) session.getAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME);
        RequestContext requestContext = new RequestContext(request);
        ResourceBundle bundle = ResourceBundle.getBundle("i18n/exception", locale);
        if (bundle.containsKey(exception.getMessage())) {
            msg = new String(bundle.getString(exception.getMessage()).getBytes("ISO-8859-1"), "UTF-8");
        }
        return new ErrResponse(exception.getCode(), msg);
    }

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                setValue(DateTimeUtil.getDate(text));
            }
        });
    }
}
